import { ref } from 'vue'
import TokenService, {type JwtPayload } from './token'


// 创建一个响应式的认证状态
const isAuthenticated = ref(TokenService.isAuthenticate())
// 认证事件处理器集合
const handlers = new Set<(authenticated: boolean) => void>()


export default {
    /**获取认证状态 */
    isAuthenticate(): boolean {
        return isAuthenticated.value
    },

    /**更新认证状态 */
    updateAuthenticate(): boolean {
        isAuthenticated.value = TokenService.isAuthenticate()
        // 通知所有订阅者
        this.notifyHandlers()
        return isAuthenticated.value
    },

    /**登录成功 */
    loginSuccess(access_token: string, refresh_token: string): void {
        // 保存tokens
        TokenService.setTokens(access_token, refresh_token)
        // 更新认证状态
        this.updateAuthenticate()
    },

    /**注销成功 */
    logoutSuccess(): void {
        // 清除tokens
        TokenService.removeTokens()
        // 更新认证状态
        this.updateAuthenticate()
    },

    /**添加认证状态变化的处理器 */
    addAuthStateHandler(handler: (authenticated: boolean) => void): void {
        handlers.add(handler)
        // 立即触发一次当前状态
        handler(this.isAuthenticate())
    },

    /**移除认证状态处理器 */
    removeAuthStateHandler(handler: (authenticated: boolean) => void): void {
        handlers.delete(handler)
    },

    /**通知所有订阅者认证状态发生变化 */
    notifyHandlers(): void {
        const currentState = this.isAuthenticate()
        handlers.forEach(handler => {
            try {
                handler(currentState)
            } catch (error) {
                console.error('Error in auth state handler:', error)
            }
        })
    },

    /**
     * 检查是否需要刷新token
     * @returns 如果access token即将过期且refresh token有效，返回true
     */
    shouldRefreshToken(): boolean {
        return !TokenService.isAccessTokenValid() && TokenService.isRefreshTokenValid()
    },

    /**
     * 获取当前用户ID
     * @returns 如果已认证，返回用户ID，否则返回null
     */
    getCurrentUserId(): string | null {
        const token = TokenService.getAccessToken()
        if (!token) return null

        const payload = TokenService.parseJwt(token)
        return payload?.sub || null
    },

    /**
     * 获取当前用户的JWT payload
     * @returns 如果已认证，返回JWT payload，否则返回null
     */
    getCurrentUserPayload(): JwtPayload | null {
        const token = TokenService.getAccessToken()
        if (!token) return null
        return TokenService.parseJwt(token)
    },

    /**
     * 检查用户是否有权限访问指定路由
     * @param requiredRoles 路由所需的角色数组
     * @returns 如果用户有权限，返回true，否则返回false
     */
    hasRouteAccess(requiredRoles?: string[]): boolean {
        // 如果路由不需要角色，则所有用户都可以访问
        if (!requiredRoles || requiredRoles.length === 0) {
            return true
        }

        // 如果路由需要认证但用户未认证，则无权访问
        if (!this.isAuthenticate()) {
            return false
        }

        // 获取用户角色
        const payload = this.getCurrentUserPayload()
        const userRoles = payload?.roles || []

        // 检查用户是否拥有所需角色
        return requiredRoles.some(role => userRoles.includes(role))
    },

}